﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.IO;

namespace ImgReceivePlus
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            TextBox.CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            int w = panel_imgs.Width;
            int h = panel_imgs.Height;
            // 在面板panel_imgs上添加显示接收到的图片的控件
            for (int i = 0; i < NUM_SLICE; i++)
            {
                // 设置PictureBox的位置、大小等参数
                PictureBox imgb = new PictureBox();
                imgb.Left = 0;
                imgb.Top = i * h / NUM_SLICE;
                imgb.Width = w;
                imgb.Height = h / NUM_SLICE + 1;
                imgb.SizeMode = PictureBoxSizeMode.StretchImage;
                imgb.Visible = true;

                // 添加到面板panel_imgs上
                imgbox[i] = imgb;                
                panel_imgs.Controls.Add(imgbox[i]);
            }

            GetLocalIPv4Address().ToString();
        }
        // 切片数量
        const int NUM_SLICE = 24; 
        // 为每一个切片创建一个显示控件
        PictureBox[] imgbox = new PictureBox[NUM_SLICE];
        // 为每一个切片创建一个UDP套接字
        Socket[] udpServer = new Socket[NUM_SLICE];

        Queue<Image>[] images = new Queue<Image>[NUM_SLICE];
        private void ImgReceive(object arg)
        {
            int port = (int)arg;
            int index = port % 8000 / 10;

            // 创建套接字
            udpServer[index] = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            // 绑定IP和端口
            udpServer[index].Bind(new IPEndPoint(IPAddress.Parse(cbb_remoteIP.Text), port));
            // 开启数据接收线程
            while (true)
            {
                EndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
                // 设置一个64k的字节数组作为缓存
                byte[] data = new byte[65536];
                int length = udpServer[index].ReceiveFrom(data, ref remoteEndPoint);//此方法把数据来源ip、port放到第二个参数中

                MemoryStream ms = new MemoryStream(data, 0, length);
                // 将图像显示到对应的PictureBox控件上
                Image img = Image.FromStream(ms);
                imgbox[index].Image = img;
                //images[0].Enqueue(img);
            }
        }

        public IPAddress GetLocalIPv4Address()
        {
            IPAddress localIpv4 = null;
            // 获取本机所有的IP地址列表
            IPAddress[] IpList = Dns.GetHostAddresses(Dns.GetHostName());
            // 循环遍历所有IP地址
            foreach (IPAddress IP in IpList)
            {
                // 判断是否是IPv4地址
                if (IP.AddressFamily == AddressFamily.InterNetwork)
                {
                    // 将得到的IPv4地址添加到下拉文本框的选项中
                    cbb_remoteIP.Items.Add(IP);
                    localIpv4 = IP;
                }
            }
            return localIpv4;
        }


        private void connectBtn_Click(object sender, EventArgs e)
        {
            
            // Parse：将一个字符串的ip地址转换成一个IPAddress对象
            IPAddress ipaddress = IPAddress.Parse(cbb_remoteIP.Text);
            EndPoint point = new IPEndPoint(ipaddress, int.Parse(cbb_remotePort.Text));

            // 开启TCP连接线程
            Thread connect = new Thread(new ParameterizedThreadStart(Connect));
            connect.Start(point);           
            
        }
        // TCP连接线程
        private void Connect(object point)
        {
            try
            {
                Socket tcpClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                tcpClient.Connect((EndPoint)point); // 通过IP和端口号来定位一个所要连接的服务器端
                                                    //connectBtn.Enabled = false;

                // 为每一个切片开启一个接收线程
                for (int i = 0; i < NUM_SLICE; i++)
                {
                    new Thread(new ParameterizedThreadStart(ImgReceive))
                    {
                        IsBackground = true
                    }.Start(8000 + i * 10);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
